package com.jcoinexchange.web.auth;

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;

import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Map;

/**
 * jwt
 */
public class JwtUtils {

    /**
     * 生成 token
     *
     * @param claims    自定义的 map
     * @param ttl 过期时间
     * @return
     */
    public static String createToken(Map<String,Object> claims, Long ttl) {
        return createToken(claims, getKey(), ttl);
    }

    /**
     *
     * @param claims claim 数据
     * @return
     */
    public static String createToken(Map<String,Object> claims) {
        return createToken(claims, 24 * 60 * 60L);
    }

    /**
     * 解密 jwt
     * @param jwt 创建的 jwt 字符串
     * @return
     */
    public static Claims parse(String jwt) {
        return parse(getKey(),jwt);
    }

    /**
     * 生成 token
     *
     * @param claims    自定义的 map
     * @param secretKey    key
     * @param ttl 过期时间 单位 秒
     * @return
     */
    private static String createToken(Map<String,Object> claims, String secretKey, Long ttl) {
        // 生成JWT的时间
        long expMillis = System.currentTimeMillis() + ttl;
        Date exp = new Date(expMillis);

        //生成 HMAC 密钥，根据提供的字节数组长度选择适当的 HMAC 算法，并返回相应的 SecretKey 对象。
        SecretKey key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));

        // 设置jwt的body
        JwtBuilder builder = Jwts.builder()
                // 设置签名使用的签名算法和签名使用的秘钥
                .signWith(key)
                // 如果有私有声明，一定要先设置这个自己创建的私有的声明，这个是给builder的claim赋值，一旦写在标准的声明赋值之后，就是覆盖了那些标准的声明的
                .claims(claims)
                // 设置过期时间
                .expiration(exp);
        return builder.compact();
    }

    /**
     * 解密 jwt
     * @param token 创建的 jwt 字符串
     * @param secretKey key
     * @return
     */
    private static Claims parse(String secretKey, String token) {
        //生成 HMAC 密钥，根据提供的字节数组长度选择适当的 HMAC 算法，并返回相应的 SecretKey 对象。
        SecretKey key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));

        // 得到DefaultJwtParser
        JwtParser jwtParser = Jwts.parser()
                // 设置签名的秘钥
                .verifyWith(key)
                .build();
        Jws<Claims> jws = jwtParser.parseSignedClaims(token);
        return jws.getPayload();
    }

    private static String getKey() {
        return  "Zk566dTntkHteEYpA3B4D021DYzpMHc2";
    }
}
